package pages

import (
	"fmt"
	"strconv"

	"github.com/GoAdminGroup/go-admin/context"
	"github.com/GoAdminGroup/go-admin/modules/config"
	"github.com/GoAdminGroup/go-admin/modules/db"
	"github.com/GoAdminGroup/go-admin/modules/language"
	aform "github.com/GoAdminGroup/go-admin/plugins/admin/modules/form"
	"github.com/GoAdminGroup/go-admin/template"
	"github.com/GoAdminGroup/go-admin/template/icon"
	"github.com/GoAdminGroup/go-admin/template/types"
	"github.com/GoAdminGroup/go-admin/template/types/form"
	selection "github.com/GoAdminGroup/go-admin/template/types/form/select"

	"mini-admin/internal/conf"
	"mini-admin/internal/database"
	"mini-admin/internal/model"
	types1 "mini-admin/internal/types"
)

// GetWechatCommitForm 获取提交代码表单
func GetWechatCommitForm(ctx *context.Context) (types.Panel, error) {

	components := template.Get(config.GetTheme())

	col1 := components.Col().GetContent()
	btn1 := components.Button().SetType("submit").
		SetContent(language.GetFromHtml("发布")).
		SetThemePrimary().
		SetOrientationRight().
		SetLoadingText(icon.Icon("fa-spinner fa-spin", 2) + `发布`).
		GetContent()
	btn2 := components.Button().SetType("reset").
		SetContent(language.GetFromHtml("Reset")).
		SetThemeWarning().
		SetOrientationLeft().
		GetContent()
	col2 := components.Col().SetSize(types.SizeMD(8)).
		SetContent(btn1 + btn2).GetContent()

	var panel = types.NewFormPanel()
	panel.AddField("微信小程序", "app_id", db.Varchar, form.SelectSingle).FieldDefault(ctx.Query("app_id")).FieldOnSearch(
		"search/wechat_mini",
		func(ctx *context.Context) (success bool, msg string, data interface{}) {
			conn := database.New(conf.Conf.ORM)
			var brandMiniApps []*model.BrandMiniApp
			if err := conn.Model(&model.BrandMiniApp{}).Where("platform = ?", types1.Wechat).Find(&brandMiniApps).Error; err != nil {
				return false, "failed", nil
			}
			appIDs := make([]string, len(brandMiniApps))
			for i, app := range brandMiniApps {
				appIDs[i] = app.AppID
			}
			var (
				appVersions    []*model.MiniAppVersion
				wechatMiniApps []*model.WechatMiniApp
			)
			if err := conn.Model(&model.MiniAppVersion{}).Where("app_id in ? and platform = ?", appIDs, types1.Wechat).Find(&appVersions).Error; err != nil {
				return false, "failed", nil
			}
			appVersionMap := make(map[string]string, len(appVersions))
			for _, version := range appVersions {
				appVersionMap[version.AppID] = version.ReleaseVersion
			}
			query := conn.Model(&model.WechatMiniApp{}).Where("app_id in ?", appIDs)
			search := ctx.Query("search")
			if search != "" {
				query = query.Where("name LIKE ?", "%"+search+"%")
			}
			if err := query.Find(&wechatMiniApps).Error; err != nil {
				return false, "failed", nil
			}
			wechatMiniAppMap := make(map[string]string, len(brandMiniApps))
			for _, app := range wechatMiniApps {
				wechatMiniAppMap[app.AppID] = app.Name
			}
			options := make(selection.Options, len(brandMiniApps))
			for i, p := range brandMiniApps {
				text := fmt.Sprintf("品牌ID:%v, %s", p.BrandID, wechatMiniAppMap[p.AppID])
				if appVersionMap[p.AppID] != "" {
					text += fmt.Sprintf("(当前版本:%s)", appVersionMap[p.AppID])
				}
				options[i] = selection.Option{
					ID:   p.AppID,
					Text: text,
				}
			}
			return true, "ok", selection.Data{
				Results: options,
			}
		}, 10).FieldMust()
	panel.AddField("微信模版ID", "template_id", db.Varchar, form.SelectSingle).FieldOnSearch("/search/wechat_template",
		func(ctx *context.Context) (success bool, msg string, data interface{}) {
			conn := database.New(conf.Conf.ORM)
			var templates []*model.WechatTemplate
			_db := conn.Model(&model.WechatTemplate{})
			search := ctx.Query("search")
			if search != "" {
				_db = _db.Where("user_desc LIKE ? OR user_version LIKE ?", "%"+search+"%", "%"+search+"%")
			}
			if err := _db.Find(&templates).Error; err != nil {
				return false, "failed", nil
			}
			options := make(selection.Options, len(templates))
			for i, t := range templates {
				options[i] = selection.Option{
					ID:   strconv.Itoa(t.TemplateID),
					Text: fmt.Sprintf("%s(%s)", t.UserVersion, t.UserDesc),
				}
			}
			return true, "ok", selection.Data{
				Results: options,
			}
		}, 10).FieldMust()

	panel.AddField("自定义ext_json", "ext_json", db.Varchar, form.TextArea)

	af := components.Form().
		SetContent(panel.FieldsWithDefaultValue()).SetHeader(panel.Header).
		SetPrefix(config.PrefixFixSlash()).
		SetUrl("/admin/form/wechat/commit").
		SetTitle("发布微信小程序").
		SetHiddenFields(map[string]string{
			aform.PreviousKey: "/admin",
		}).
		SetOperationFooter(col1 + col2)

	return types.Panel{
		Content: components.Box().
			SetHeader(af.GetDefaultBoxHeader(true)).
			WithHeadBorder().
			SetBody(af.GetContent()).
			GetContent(),
		Title:       "发布指定微信小程序",
		Callbacks:   panel.Callbacks,
		Description: "发布指定微信小程序",
	}, nil
}

// GetAlipayCommitForm 获取提交代码表单
func GetAlipayCommitForm(ctx *context.Context) (types.Panel, error) {

	components := template.Get(config.GetTheme())

	col1 := components.Col().GetContent()
	btn1 := components.Button().SetType("submit").
		SetContent(language.GetFromHtml("发布")).
		SetThemePrimary().
		SetOrientationRight().
		SetLoadingText(icon.Icon("fa-spinner fa-spin", 2) + `发布`).
		GetContent()
	btn2 := components.Button().SetType("reset").
		SetContent(language.GetFromHtml("Reset")).
		SetThemeWarning().
		SetOrientationLeft().
		GetContent()
	col2 := components.Col().SetSize(types.SizeMD(8)).
		SetContent(btn1 + btn2).GetContent()

	var panel = types.NewFormPanel()
	panel.AddField("支付宝", "app_id", db.Varchar, form.SelectSingle).FieldDefault(ctx.Query("app_id")).FieldOnSearch(
		"search/alipay_mini",
		func(ctx *context.Context) (success bool, msg string, data interface{}) {
			conn := database.New(conf.Conf.ORM)
			var brandMiniApps []*model.BrandMiniApp
			if err := conn.Model(&model.BrandMiniApp{}).Where("platform = ?", types1.Alipay).Find(&brandMiniApps).Error; err != nil {
				return false, "failed", nil
			}
			appIDs := make([]string, len(brandMiniApps))
			for i, app := range brandMiniApps {
				appIDs[i] = app.AppID
			}

			var (
				appVersions    []*model.MiniAppVersion
				alipayMiniApps []*model.AlipayMiniApp
			)
			if err := conn.Model(&model.MiniAppVersion{}).Where("app_id in ? and platform = ?", appIDs, types1.Alipay).Find(&appVersions).Error; err != nil {
				return false, "failed", nil
			}
			appVersionMap := make(map[string]string, len(appVersions))
			for _, version := range appVersions {
				appVersionMap[version.AppID] = version.ReleaseVersion
			}
			query := conn.Model(&model.AlipayMiniApp{}).Where("app_id in ?", appIDs)
			search := ctx.Query("search")
			if search != "" {
				query = query.Where("name LIKE ?", "%"+search+"%")
			}
			if err := query.Find(&alipayMiniApps).Error; err != nil {
				return false, "failed", nil
			}
			alipayMiniAppMap := make(map[string]string, len(brandMiniApps))
			for _, app := range alipayMiniApps {
				alipayMiniAppMap[app.AppID] = app.Name
			}
			options := make(selection.Options, len(brandMiniApps))
			for i, p := range brandMiniApps {
				text := fmt.Sprintf("品牌ID:%v, %s", p.BrandID, alipayMiniAppMap[p.AppID])
				if appVersionMap[p.AppID] != "" {
					text += fmt.Sprintf("(当前版本:%s)", appVersionMap[p.AppID])
				}
				options[i] = selection.Option{
					ID:   p.AppID,
					Text: text,
				}
			}
			return true, "ok", selection.Data{
				Results: options,
			}
		}, 10).FieldMust()
	panel.AddField("支付宝模版ID", "template_id", db.Varchar, form.SelectSingle).FieldOnSearch("/search/alipay_template",
		func(ctx *context.Context) (success bool, msg string, data interface{}) {
			conn := database.New(conf.Conf.ORM)
			var templates []*model.AlipayTemplate
			_db := conn.Model(&model.AlipayTemplate{})
			search := ctx.Query("search")
			if search != "" {
				_db = _db.Where("version_desc LIKE ? OR app_version LIKE ?", "%"+search+"%", "%"+search+"%")
			}
			if err := _db.Find(&templates).Error; err != nil {
				return false, "failed", nil
			}
			options := make(selection.Options, len(templates))
			for i, t := range templates {
				options[i] = selection.Option{
					ID:   t.TemplateID,
					Text: fmt.Sprintf("%s(%s)", t.AppVersion, t.VersionDesc),
				}
			}
			return true, "ok", selection.Data{
				Results: options,
			}
		}, 10).FieldMust()

	af := components.Form().
		SetContent(panel.FieldsWithDefaultValue()).SetHeader(panel.Header).
		SetPrefix(config.PrefixFixSlash()).
		SetUrl("/admin/form/alipay/commit").
		SetTitle("发布支付宝小程序").
		SetHiddenFields(map[string]string{
			aform.PreviousKey: "/admin",
		}).
		SetOperationFooter(col1 + col2)

	return types.Panel{
		Content: components.Box().
			SetHeader(af.GetDefaultBoxHeader(true)).
			WithHeadBorder().
			SetBody(af.GetContent()).
			GetContent(),
		Title:       "发布指定支付宝小程序",
		Callbacks:   panel.Callbacks,
		Description: "发布指定支付宝小程序",
	}, nil
}

// GetBytedanceCommitForm 获取提交代码表单
func GetBytedanceCommitForm(ctx *context.Context) (types.Panel, error) {

	components := template.Get(config.GetTheme())

	col1 := components.Col().GetContent()
	btn1 := components.Button().SetType("submit").
		SetContent(language.GetFromHtml("发布")).
		SetThemePrimary().
		SetOrientationRight().
		SetLoadingText(icon.Icon("fa-spinner fa-spin", 2) + `发布`).
		GetContent()
	btn2 := components.Button().SetType("reset").
		SetContent(language.GetFromHtml("Reset")).
		SetThemeWarning().
		SetOrientationLeft().
		GetContent()
	col2 := components.Col().SetSize(types.SizeMD(8)).
		SetContent(btn1 + btn2).GetContent()

	var panel = types.NewFormPanel()
	panel.AddField("字节跳动小程序", "app_id", db.Varchar, form.SelectSingle).FieldDefault(ctx.Query("app_id")).FieldOnSearch(
		"search/bytedance_mini",
		func(ctx *context.Context) (success bool, msg string, data interface{}) {
			conn := database.New(conf.Conf.ORM)
			var brandMiniApps []*model.BrandMiniApp
			if err := conn.Model(&model.BrandMiniApp{}).Where("platform = ?", types1.Wechat).Find(&brandMiniApps).Error; err != nil {
				return false, "failed", nil
			}
			appIDs := make([]string, len(brandMiniApps))
			for i, app := range brandMiniApps {
				appIDs[i] = app.AppID
			}
			var (
				appVersions       []*model.MiniAppVersion
				bytedanceMiniApps []*model.BytedanceMiniApp
			)
			if err := conn.Model(&model.MiniAppVersion{}).Where("app_id in ? and platform = ?", appIDs, types1.ByteDance).Find(&appVersions).Error; err != nil {
				return false, "failed", nil
			}
			appVersionMap := make(map[string]string, len(appVersions))
			for _, version := range appVersions {
				appVersionMap[version.AppID] = version.ReleaseVersion
			}
			query := conn.Model(&model.WechatMiniApp{}).Where("app_id in ?", appIDs)
			search := ctx.Query("search")
			if search != "" {
				query = query.Where("name LIKE ?", "%"+search+"%")
			}
			if err := query.Find(&bytedanceMiniApps).Error; err != nil {
				return false, "failed", nil
			}
			wechatMiniAppMap := make(map[string]string, len(brandMiniApps))
			for _, app := range bytedanceMiniApps {
				wechatMiniAppMap[app.AppID] = app.Name
			}
			options := make(selection.Options, len(brandMiniApps))
			for i, p := range brandMiniApps {
				text := fmt.Sprintf("品牌ID:%v, %s", p.BrandID, wechatMiniAppMap[p.AppID])
				if appVersionMap[p.AppID] != "" {
					text += fmt.Sprintf("(当前版本:%s)", appVersionMap[p.AppID])
				}
				options[i] = selection.Option{
					ID:   p.AppID,
					Text: text,
				}
			}
			return true, "ok", selection.Data{
				Results: options,
			}
		}, 10).FieldMust()
	panel.AddField("字节跳动模版ID", "template_id", db.Varchar, form.SelectSingle).FieldOnSearch("/search/bytedance_template",
		func(ctx *context.Context) (success bool, msg string, data interface{}) {
			conn := database.New(conf.Conf.ORM)
			var templates []*model.BytedanceTemplate
			_db := conn.Model(&model.BytedanceTemplate{})
			search := ctx.Query("search")
			if search != "" {
				_db = _db.Where("user_desc LIKE ? OR user_version LIKE ?", "%"+search+"%", "%"+search+"%")
			}
			if err := _db.Find(&templates).Error; err != nil {
				return false, "failed", nil
			}
			options := make(selection.Options, len(templates))
			for i, t := range templates {
				options[i] = selection.Option{
					ID:   strconv.Itoa(t.TemplateID),
					Text: fmt.Sprintf("%s(%s)", t.UserVersion, t.UserDesc),
				}
			}
			return true, "ok", selection.Data{
				Results: options,
			}
		}, 10).FieldMust()

	af := components.Form().
		SetContent(panel.FieldsWithDefaultValue()).SetHeader(panel.Header).
		SetPrefix(config.PrefixFixSlash()).
		SetUrl("/admin/form/bytedance/commit").
		SetTitle("发布字节跳动小程序").
		SetHiddenFields(map[string]string{
			aform.PreviousKey: "/admin",
		}).
		SetOperationFooter(col1 + col2)

	return types.Panel{
		Content: components.Box().
			SetHeader(af.GetDefaultBoxHeader(true)).
			WithHeadBorder().
			SetBody(af.GetContent()).
			GetContent(),
		Title:       "发布指定字节跳动小程序",
		Callbacks:   panel.Callbacks,
		Description: "发布指定字节跳动小程序",
	}, nil
}
